package com.xbongbong.paas.service.stage.jump;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasStageEntity;
import com.xbongbong.paas.domain.entity.StageLogEntity;
import com.xbongbong.paas.domain.entity.StageProcessEntity;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.help.ProUpdateHelp;
import com.xbongbong.paas.service.stage.StageHandle;
import com.xbongbong.paas.service.stage.StageHandleFactory;
import com.xbongbong.paas.service.stage.StageJumpHandle;
import com.xbongbong.paas.service.stage.StageLogHandle;
import com.xbongbong.paas.service.stage.StageLogHandleFactory;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.factory.StageExecuteFactory;
import com.xbongbong.parent.interfaces.StageExecuteHandle;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpDealDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpSpecialDealDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpValidateDTO;
import com.xbongbong.pro.businesstage.pojo.vo.StageJumpDealVO;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.PaasStageEnum;
import com.xbongbong.pro.enums.errorcodes.CustomerStageErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Auther: yingjianfeng
 * @Date: 2021/12/3 14:55
 * @Description: 开始阶段跳转策略
 */
@Service("startStageJumpHandleImpl")
@Slf4j
public class StartStageJumpHandleImpl extends AbstractStageJumpHandle implements StageJumpHandle {

    @Resource
    private StageHandleFactory stageHandleFactory;
    @Resource
    private StageExecuteFactory stageExecuteFactory;
    @Resource
    private StageLogHandleFactory stageLogHandleFactory;
    @Resource
    private ProUpdateHelp proUpdateHelp;

    @Override
    public Integer type() {
        return StageTypeEnum.START_STAGE.getType();
    }

    @Override
    public StageJumpDealVO jumpDeal(StageJumpDealDTO stageJumpDealDTO) throws XbbException {
        // 跳入开始阶段处理
        try {
            log.info("===========跳转至开始阶段===========");
            Integer saasMark = stageJumpDealDTO.getSaasMark();
            Integer businessType = stageJumpDealDTO.getBusinessType();
            Long dataId = stageJumpDealDTO.getDataId();
            PaasStageEntity fromStageEntity = stageJumpDealDTO.getFromStageEntity();
            List<PaasStageEntity> rangeStageEntitys = stageJumpDealDTO.getRangeStageEntitys();
            rangeStageEntitys.add(fromStageEntity);
            String corpid = stageJumpDealDTO.getCorpid();
            Long formId = stageJumpDealDTO.getFormId();
            StageExecuteHandle stageExecute = stageExecuteFactory.getStageExecute(saasMark, businessType);
            StageLogHandle stageLogHandle = stageLogHandleFactory.getStageLogHandle(saasMark, businessType);
            List<Long> stageIdIn = new ArrayList();
            for (PaasStageEntity temp : rangeStageEntitys) {
                stageIdIn.add(temp.getId());
            }
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            StageLogEntity nowStageLogEntity = null;
            // 获取区间和 from的stagelog
            if (CollectionsUtil.isNotEmpty(stageIdIn)) {
                params.put("corpid", corpid);
                params.put("formId", formId);
                params.put("dataId", dataId);
                params.put("stageIdIn", stageIdIn);
                params.put("del", 0);
                List<StageLogEntity> stageLogEntities = stageLogHandle.findEntitys(params);
                for (StageLogEntity temp : stageLogEntities) {
                    Integer isNow = temp.getIsNow();
                    if (Objects.equals(isNow, 1)) {
                        nowStageLogEntity = temp;
                    }
                }
            }
            Long now = DateTimeUtil.getInt();
            nowStageLogEntity.setOutTime(0L);
            nowStageLogEntity.setIsNow(0);
            //计算规则为history_stay_time=history_stay_time+out_time-into_time  
            nowStageLogEntity.setHistoryStayTime(nowStageLogEntity.getHistoryStayTime() + now - nowStageLogEntity.getIntoTime());
            stageLogHandle.save(nowStageLogEntity);
            // 更新比例  通过了校验肯定是能进入开始阶段的  进入开始阶段 需要取第一个阶段的进入比例
            Integer stageRatioValue = rangeStageEntitys.get(0).getIntoProportion();
            if (stageRatioValue == null) {
                stageRatioValue = 0;
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(PaasStageEnum.STAGE_RATIO.getAttr(), stageRatioValue);
            jsonObject.put(PaasStageEnum.STAGE_ID.getAttr(), null);
            UpdateDataEntity updateData = ExplainUtil.getUpdateData(dataId, jsonObject, corpid);
            proUpdateHelp.updateBatch(saasMark, businessType, corpid, Collections.singletonList(updateData));
            //开始处理特殊逻辑
            StageJumpSpecialDealDTO stageJumpSpecialDealDTO = new StageJumpSpecialDealDTO();
            BeanUtils.copyProperties(stageJumpDealDTO, stageJumpSpecialDealDTO);
            stageExecute.jumpSpecialDeal(stageJumpSpecialDealDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            log.error("阶段跳转至开始阶段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return null;
    }

    @Override
    public void validate(StageJumpValidateDTO stageJumpValidateDTO) throws XbbException {
        StageProcessEntity stageProcessEntity = stageJumpValidateDTO.getStageProcessEntity();
        PaasStageEntity fromStageEntity = stageJumpValidateDTO.getFromStageEntity();
        String corpid = stageJumpValidateDTO.getCorpid();
        Long formId = stageJumpValidateDTO.getFormId();
        Integer businessType = stageJumpValidateDTO.getBusinessType();
        Integer saasMark = stageJumpValidateDTO.getSaasMark();
        Integer fromStageType = stageJumpValidateDTO.getFromStageType();
        // 回退校验
        Integer allowBack = stageProcessEntity.getAllowBack();
        if (Objects.equals(allowBack, 0)) {
            //不满足回退校验，无法跳转
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238044);
        }
        // 跨阶段校验
        Integer sort = fromStageEntity.getSort();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("formId", formId);
        params.put("stageProcessId", stageProcessEntity.getId());
        params.put("enable", 1);
        params.put("del", 0);
        params.put("sortGreater", sort);  // 大于当前sort的
        StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
        List<PaasStageEntity> paasStageEntityList = stageHandle.findEntitys(params);
        if (Objects.isNull(paasStageEntityList)) {
            stageJumpValidateDTO.setRangeStageEntitys(new ArrayList<>());
        } else {
            stageJumpValidateDTO.setRangeStageEntitys(paasStageEntityList);
        }
        for (PaasStageEntity temp : paasStageEntityList) {
            Integer allowSkipStage = temp.getAllowSkipStage();
            Integer type = temp.getType();
            if (!Objects.equals(type, 0)) {
                continue;
            }
            if (Objects.equals(allowSkipStage, 0)) {
                //中间有阶段不允许跨过，无法跳转
                throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238043);
            }
        }
        // 特殊判断下 从开始或失败阶段过来的不允许跳转
        if (Objects.equals(fromStageType, StageTypeEnum.FAIL_STAGE.getType()) || Objects.equals(fromStageType, StageTypeEnum.SUCCESS_STAGE.getType())) {
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238046);
        }
    }

    @Override
    public Integer getJumpIntoProportion(Long dataId, String corpid, Long formId, Long stageId, Integer saasMark, Integer businessType, Integer outProportion) throws XbbException{
        return null;
    }
}
